package tota.agent;

import java.util.*;

import emulator.peers.*;
import emulator.utils.GenPoint;
import emulator.agent.*;
import tota.middleware.*;

import tuplespace.tuples.*;
import tota.tuples.*;
import tota.tuples.hop.GradientTuple;

public class AgentTotaEXP extends AbstractAgent {
	static boolean REALTIME_SCREEN_UPDATE = true;

	PeerInterface_ApplicationSide peer;

	TotaMiddleware tota;

	public AgentTotaEXP(PeerInterface_ApplicationSide peer) {
		this.peer = peer;
		tota = new TotaMiddleware(peer);
		System.out.println(peer.getAddress() + " starting...");
		if (peer.getAddress().equals("192.168.0.0")) 
		 move(275, 110);
	}

	public void inject(String tuple, String content) {
		TotaTuple t = (TotaTuple) createTuple(tuple);
		if (t == null)
			return;
		t.setContent(content);
		tota.inject(t);
	}

	public void remove(String tuple, String content) {
		TotaTuple t = (TotaTuple) createTuple(tuple);
		if (t == null)
			return;
		t.setContent(content);

		Vector v = tota.read(t);
		for (int i = 0; i < v.size(); i++) {
			Tuple delT = (Tuple) v.get(i);
			tota.delete(delT);
		}
	}

	private Tuple createTuple(String tuple) {
		Tuple t;
		try {
			Class clazz = Class.forName("tota.tuples." + tuple);
			t = (Tuple) clazz.newInstance();
		} catch (Exception e) {
			System.err.println("Cannot create the tuple!");
			e.printStackTrace();
			return null;
		}
		return t;
	}

	private void move(int x, int y) {
		Peer p = (Peer) peer.getRealIdentity();
		p.emu.move(p.toString(), new GenPoint(x, y));
	}
	
	
	private void printTuples(int time) {
	 System.out.println("*** "+time+": "+peer.getAddress());
     Tuple t = createTuple("hop.GradientTuple");
	 t.setContent("<content=ciao>");
	 // read own tuple space
	 Vector v = tota.read(t);
	 for(int i=0; i<v.size();i++) 
	  System.out.println("own "+((GradientTuple)v.get(i)).hop);
	 // read neighbor tuple space
	 Vector vn = tota.readOneHop(t);
	 for(int i=0; i<vn.size();i++) 
	  System.out.println("neigh "+((GradientTuple)vn.get(i)).hop);
	}

	/** ************************************************************************** */
	/* AGENT INTERFACE METHODS */
	/***************************************************************************
	 * These metohds wouldn't be actually required by the real agents that
	 * simply would display this panel in their user interface. However they are
	 * needed for /
	 **************************************************************************/
	public void step(int time) {
		tota.step(time);
		
		if (time == 20) {
            
			if (peer.getAddress().equals("192.168.0.0")) {
				System.out.println("\n\n\n");
				inject("hop.GradientTuple", "<content=ciao>");
			}

		}
		/*
		if(time == 90)
		 printTuples(time); 
        */
		/*
		 * TIME = 100 The node 0 moves out of the network
		 */
        /*
		if (time == 100) {
            
			
			
			if (peer.getAddress().equals("192.168.0.0")) {
				System.out.println("\n\n\n");
				move(275, 110);
			}
		}
		
		
		if(time == 290)
			 printTuples(time); 
        */
		/*
		 * TIME = 300 The node 0 moves on the other side of the network
		 */

		if (time == 200) {
            
			if (peer.getAddress().equals("192.168.0.0")) {
				System.out.println("\n\n\n");
				move(475, 100);
			}

		}
		
		
		if(time == 490) printTuples(time); 
		if(time == 600) System.out.println();
		if(time == 690) printTuples(time); 
		
		/*
		
		//  TIME = 500 The node 0 moves out of the network
		

		if (time == 500) {
			
			if(peer.getAddress().equals("192.168.0.0")) {
				System.out.println("\n\n\n");
				move(300, 300);
			}
		}
		
		
		if(time == 690)
			 printTuples(time); 
		
		
		
		// TIME = 700 The node 0 moves at the begining of the network
		 

		if (time == 700) {
			
			if(peer.getAddress().equals("192.168.0.0")) {
				System.out.println("\n\n\n");
				move(100, 100);
			}
		}
			
		
		if(time == 890)
			 printTuples(time); 
		

		
		// TIME = 900 The node 0 moves out of the network
		 

		if (time == 900) {
			
			if(peer.getAddress().equals("192.168.0.0")) {
				System.out.println("\n\n\n");
				move(300, 300);
			}
		}
		
		if(time == 1090)
		 printTuples(time); 
		
		*/
	}

	public synchronized void showAgentFrame() {
	}

	public synchronized void hideAgentFrame() {
		peer.shutDown();
	}

	public synchronized Object getRealIdentity() {
		return this;
	}
}